import { ResultSelect } from './../tools/modHelper';
import { ModeEvent } from "../tools/ModeEvent";
import { getModeFuncRet, RetResult } from "../tools/modHelper";

export type OpenResult =
  | "OpenCompleted"
  | "ConnectionOpened"
  | "DeviceError"
  | "Timeout"
  | "FatalError";

  
export class BaseIO<S, C> extends ModeEvent {
  protected isOpen: boolean;
  constructor(modName: string, mod: any) {
    super(modName, mod);
    this.isOpen = false;
  }
  Open(logic: string, timeout: number) {
    this.setCurrentMethod("Open");
    this.removeMethodBindEvt("Open");
    return new Promise<RetResult<OpenResult>>((resolve) => {
      const OpenCompleted = (...args: any[]) => {
        this.isOpen = true;
        console.log("OpenCompleted");
        resolve(getModeFuncRet(this.modName, 'OpenCompleted', args));
      };
      const ConnectionOpened = (...args: any[]) => {
        this.isOpen = true;
        console.log("ConnectionOpened");
        resolve(getModeFuncRet(this.modName, "ConnectionOpened", args));
      };
      const DeviceError = (...args: any[]) => {
        console.log("DeviceError");
        resolve(getModeFuncRet(this.modName, "DeviceError", args));
      };
      const Timeout = (...args: any[]) => {
        console.log("Timeout");
        resolve(getModeFuncRet(this.modName, "Timeout", args));
      };
      const FatalError = (...args: any[]) => {
        console.log("FatalError");
        resolve(getModeFuncRet(this.modName, "FatalError", args));
      };
      this.add("OpenCompleted", OpenCompleted);
      this.add("ConnectionOpened", ConnectionOpened);
      this.add("DeviceError", DeviceError);
      this.add("Timeout", Timeout);
      this.add("FatalError", FatalError);
      this.mod.Open(logic, timeout, (ret: string) => {
        console.log(ret);
      });
    }).then((ret) => {
      this.removeMethodBindEvt("Open");
      return ret;
    });
  }

  GetState() {
  // type A<T> = T extends Promise<unknown> ? T : Result2<T>
  // type B = A<CimState>

    return new Promise<ResultSelect<S>>((resolve) => {
      this.mod.GetState((ret: string) => {
        resolve(JSON.parse(ret));
      });
    });
  }
  GetCapability() {
    return new Promise<ResultSelect<C>>((resolve) => {
      this.mod.GetCapability((ret: string) => {
        resolve(JSON.parse(ret));
      });
    });
  }
  
  UpdateDeviceStatus() {
    return new Promise<void>((resolve) => {
      this.mod.OnUpdateDeviceStatus((ret: string) => {
        resolve();
      });
    });
  }

  // Reset(arg1?: any, ...args: any[]) {
  //   return new Promise<void>((resolve) => {
  //     this.mod.Reset(arg1, ...args, (ret: string) => {
  //       resolve();
  //     });
  //   });
  // }
}
